#include <gst/gst.h>

int main(int argc, char* argv[])
{
    GstElement *pipeline, *source, *filter, *convert, *sink;
    GstBus* bus;
    GstMessage* msg;

    /* 初始化 GStreamer */
    gst_init(&argc, &argv);

    /* 创建一个空的 pipeline */
    pipeline = gst_pipeline_new("video-player");

    /* 创建一个视频源 */
    source = gst_element_factory_make("v4l2src", "source");
    g_object_set(source, "device", "/dev/video0", NULL);

    /* 创建一个 capsfilter 来设置捕获的格式和分辨率 */
    GstCaps* caps = gst_caps_new_simple("video/x-raw",
        "format", G_TYPE_STRING, "YUY2",
        "width", G_TYPE_INT, 256,
        "height", G_TYPE_INT, 192,
        "framerate", GST_TYPE_FRACTION, 25, 1,
        NULL);
    filter = gst_element_factory_make("capsfilter", "filter");
    g_object_set(filter, "caps", caps, NULL);
    gst_caps_unref(caps);

    /* 创建一个视频转化器 */
    convert = gst_element_factory_make("videoconvert", "video-convert");

    /* 创建一个视频输出 */
    sink = gst_element_factory_make("fpsdisplaysink", "video-output");

    /* 检查元素是否都创建成功 */
    if (!pipeline || !source || !filter || !convert || !sink) {
        g_printerr("Not all elements could be created.\n");
        return -1;
    }

    /* 构建 pipeline */
    gst_bin_add_many(GST_BIN(pipeline), source, filter, convert, sink, NULL);
    if (gst_element_link_many(source, filter, convert, sink, NULL) != TRUE) {
        g_printerr("Elements could not be linked.\n");
        gst_object_unref(pipeline);
        return -1;
    }

    /* 开始播放 */
    gst_element_set_state(pipeline, GST_STATE_PLAYING);

    /* 等待错误或 EOS */
    bus = gst_element_get_bus(pipeline);
    msg = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR);
    msg = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_EOS);

    /* 释放资源 */
    if (msg != NULL)
        gst_message_unref(msg);

    gst_object_unref(bus);
    gst_element_set_state(pipeline, GST_STATE_NULL);
    gst_object_unref(pipeline);
    return 0;
}